/*
 * Copyright (C) 2001-2005 Pleasant nightmare studio
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package org.pleasantnightmare.acake;

import org.junit.Assert;
import org.pleasantnightmare.acake.errorhandling.CheckError;
import org.pleasantnightmare.acake.errorhandling.ErrorHandler;

import javax.tools.Diagnostic;
import java.util.LinkedList;
import java.util.List;

/**
 * Error handler implementation used in unit tests.
 * <p/>
 * First, you must set CheckError you're expecting via
 * <code>expectError(CheckError)</code>
 * <p/>
 * Then you run your test, and processor reports
 * failure to this handler.
 * <p/>
 * On the end of unit test, you should call
 * <code>check()</code> to make error handler check
 * for any expected errors. The call will continue normally
 * if processor reported expected error. Otherwise,
 * Assert.fail() will be called with check error
 * that was expected.
 *
 * @author deus
 * @version 1.0
 * @since Nov 17, 2009 10:59:21 AM
 */
public class UnitTestErrorHandler implements ErrorHandler {
    private List<CheckError> expectedErrors;
    private List<CheckError> reportedErrors;

    public UnitTestErrorHandler() {
        expectedErrors = new LinkedList<CheckError>();
        reportedErrors = new LinkedList<CheckError>();
    }

    @Override
    public void report(CheckError checkError) {
        reportedErrors.add(checkError);
    }

    @Override
    public void printMessage(Diagnostic.Kind note, String message) {
        System.err.println("[" + note.toString() + "]" + message);
    }

    public void check() {
        if (reportedErrors.size() < expectedErrors.size())
            Assert.fail("Got MORE reported errors than expected, reported: " + reportedErrors.size() + ", expected: " + expectedErrors.size() + "\n Reported errors: " + reportedErrors);
        if (reportedErrors.size() > expectedErrors.size())
            Assert.fail("Got LESS reported errors than expected, reported: " + reportedErrors.size() + ", expected: " + expectedErrors.size() + "\n Reported errors: " + reportedErrors);

        for (int i = 0; i < expectedErrors.size(); i++) {
            CheckError expectedError = expectedErrors.get(i);
            CheckError reportedError = reportedErrors.get(i);
            if (!expectedError.equals(reportedError))
                Assert.fail("Error number: " + i + "\nExpected: " + expectedErrors + "\nReceived: " + reportedErrors);
        }
    }

    public void expectError(CheckError expectedError) {
        expectedErrors.add(expectedError);
    }
}
